package com.xzq.erp.controller;

import com.xzq.erp.aspect.ApiOperationLog;
import com.xzq.erp.domain.vo.*;
import com.xzq.erp.enums.*;
import com.xzq.erp.service.*;
import com.xzq.erp.service.impl.ComplaintReplyServiceImpl;
import com.xzq.erp.utils.ExcelUtils;
import com.xzq.erp.utils.ExcelUtils.ColumnConfig;
import com.xzq.erp.utils.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Excel导出控制器
 */
@RestController
@RequestMapping("/excel")
@Tag(name = "Excel导出相关接口")
@RequiredArgsConstructor
@Slf4j
public class ExcelExportController {

    private final ICustomerService customerService;
    private final IOrderService orderService;
    private final ISalesOpportunityService salesOpportunityService;
    private final IAfterSalesServiceService afterSalesService;
    private final IComplaintReplyService complaintReplyService;
    private final IProductService productService;
    private final IProductStockService productStockService;

    /**
     * 导出客户列表
     */
    @GetMapping("/customers/export")
    @Operation(summary = "导出客户列表")
    @ApiOperationLog(description = "导出客户列表")
    @PreAuthorize("hasAuthority('customer:list') || hasRole('ADMIN')")
    public void exportCustomers(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<CustomerVO> customers = customerService.getAllCustomers();
        
        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("客户ID", "id"));
        columnConfigs.add(ColumnConfig.of("客户名称", "customerName"));
        columnConfigs.add(ColumnConfig.of("地址", "address"));
        columnConfigs.add(ColumnConfig.of("联系电话", "phone"));
        columnConfigs.add(
                ColumnConfig.of("客户类型", "customerType")
                        .withFormatter(value -> {
                            try{
                                CustomerType customerType = (CustomerType) value;
                                return customerType.getDesc();
                            }
                            catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(
                ColumnConfig.of("客户等级", "grade")
                        .withFormatter(value -> {
                            try{
                                CustomerGrade customerType = (CustomerGrade) value;
                                return customerType.getDesc();
                            }
                            catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(ColumnConfig.of("历史成绩金额", "historicalTotal").withDecimalFormat("%.2f"));
        columnConfigs.add(ColumnConfig.of("创建时间", "createTime").withDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 3. 设置响应头
        ExcelUtils.setExcelResponseHeader(response, "客户列表");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(customers, columnConfigs, response.getOutputStream());
    }

    /**
     * 导出订单列表
     */
    @GetMapping("/orders/export")
    @Operation(summary = "导出订单列表")
    @ApiOperationLog(description = "导出订单列表")
    @PreAuthorize("hasAuthority('order:list') || hasRole('ADMIN')")
    public void exportOrders(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<OrderVO> orders = orderService.getAllOrders();

        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("订单ID", "id"));
        columnConfigs.add(ColumnConfig.of("客户名称", "customerName"));
        columnConfigs.add(ColumnConfig.of("商品名称", "productName"));
        columnConfigs.add(ColumnConfig.of("购买数量", "quantity"));
        columnConfigs.add(ColumnConfig.of("订单状态", "status")
                .withFormatter(value -> {
                    try{
                        OrderStatus orderStatus = (OrderStatus) value;
                        return orderStatus.getDesc();
                    }
                    catch (Exception e) {
                        return "未知";
                    }
                }));
        columnConfigs.add(ColumnConfig.of("支付状态", "paymentMethod")
                .withFormatter(value -> {
                    try{
                        PaymentMethod paymentMethod = (PaymentMethod) value;
                        return paymentMethod.getDesc();
                    }
                    catch (Exception e) {
                        return "未知";
                    }
                }));
        columnConfigs.add(ColumnConfig.of("支付金额", "paymentAmount").withDecimalFormat("%.2f"));
        columnConfigs.add(ColumnConfig.of("创建时间", "orderDate").withDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 3. 设置响应头
        ExcelUtils.setExcelResponseHeader(response, "订单列表");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(orders, columnConfigs, response.getOutputStream());
    }

    /**
     * 导出销售机会列表
     */
    @GetMapping("/sales-opportunities/export")
    @Operation(summary = "导出销售机会列表")
    @ApiOperationLog(description = "导出销售机会列表")
    @PreAuthorize("hasAuthority('salesOpportunity:list') || hasRole('ADMIN')")
    public void exportSalesOpportunities(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<SalesOpportunityVO> salesOpportunities = salesOpportunityService.getAllSalesOpportunities();

        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("ID", "id"));
        columnConfigs.add(ColumnConfig.of("客户ID", "customerId"));
        columnConfigs.add(ColumnConfig.of("客户名称", "customerName"));
        columnConfigs.add(ColumnConfig.of("渠道ID", "channelId"));
        columnConfigs.add(ColumnConfig.of("渠道名称", "channelName"));
        columnConfigs.add(
                ColumnConfig.of("渠道类型", "channelType")
                        .withFormatter(value -> {
                            try{
                                ChannelType channelType = (ChannelType) value;
                                return channelType.getDesc();
                            }
                            catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(ColumnConfig.of("预期金额", "expectedAmount").withDecimalFormat("%.2f"));
        columnConfigs.add(ColumnConfig.of("当前阶段", "currentStage")
                .withFormatter(value -> {
                    try {
                        CurrentStage currentStage = (CurrentStage) value;
                        return currentStage.getDesc();
                    } catch (Exception e) {
                        return "未知";
                    }
                }));
        columnConfigs.add(ColumnConfig.of("员工ID", "employeeId"));
        columnConfigs.add(ColumnConfig.of("创建时间", "createTime").withDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 3. 设置响应头
        ExcelUtils.setExcelResponseHeader(response, "销售机会列表");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(salesOpportunities, columnConfigs, response.getOutputStream());
    }

    /**
     * 导出服务记录
     */
    @GetMapping("/records/export")
    @Operation(summary = "导出服务记录")
    @ApiOperationLog(description = "导出服务记录")
    @PreAuthorize("hasAuthority('serviceRecord:list') || hasRole('ADMIN')")
    public void exportServiceRecords(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<AfterSalesServiceVO> serviceRecords = afterSalesService.getAllServiceRecords();
        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("ID", "id"));
        columnConfigs.add(ColumnConfig.of("客户名称", "customerName"));
        columnConfigs.add(
                ColumnConfig.of("问题类型", "problemType")
                        .withFormatter(value -> {
                            try {
                                ProblemType problemType = (ProblemType) value;
                                return problemType.getDesc();
                            } catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(
                ColumnConfig.of("售后优先级", "priority")
                        .withFormatter(value -> {
                            try {
                                Priority priority = (Priority) value;
                                return priority.getDesc();
                            } catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(
                ColumnConfig.of("处理状态", "status")
                        .withFormatter(value -> {
                            try {
                                AfterSalesServiceStatus status = (AfterSalesServiceStatus) value;
                                return status.getDesc();
                            } catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(ColumnConfig.of("满意度", "satisfactionScore"));
        columnConfigs.add(ColumnConfig.of("创建时间", "createTime").withDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 3. 设置响应头
        ExcelUtils.setExcelResponseHeader(response, "服务记录");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(serviceRecords, columnConfigs, response.getOutputStream());
    }

    /**
     * 导出投诉回复
     */
    @GetMapping("/complaint-replies/export")
    @Operation(summary = "导出投诉回复")
    @ApiOperationLog(description = "导出投诉回复")
    public void exportComplaintReplies(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<ComplaintReplyVO> complaintReplies = complaintReplyService.getAllComplaintReplies();
        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("ID", "id"));
        columnConfigs.add(ColumnConfig.of("售后服务ID", "afterSalesId"));
        columnConfigs.add(ColumnConfig.of("投诉人", "customerName"));
        columnConfigs.add(ColumnConfig.of("投诉内容", "complaintContent"));
        columnConfigs.add(ColumnConfig.of("回复内容", "replyContent"));
        columnConfigs.add(ColumnConfig.of("回复时间", "replyTime").withDateFormat("yyyy-MM-dd HH:mm:ss"));
        columnConfigs.add(ColumnConfig.of("满意度评分", "satisfactionLevel"));
        columnConfigs.add(ColumnConfig.of("创建时间", "createTime").withDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 3. 配置响应头
        ExcelUtils.setExcelResponseHeader(response, "投诉回复");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(complaintReplies, columnConfigs, response.getOutputStream());
    }

    /**
     * 导出商品管理
     */
    @GetMapping("/products/export")
    @Operation(summary = "导出商品管理")
    @ApiOperationLog(description = "导出商品管理")
    public void exportProducts(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<ProductVO> products = productService.getAllProducts();
        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("商品ID", "id"));
        columnConfigs.add(ColumnConfig.of("商品名称", "name"));
        columnConfigs.add(ColumnConfig.of("分类ID", "categoryId"));
        columnConfigs.add(ColumnConfig.of("分类名称", "categoryName"));
        columnConfigs.add(ColumnConfig.of("分类父级ID", "categoryParentId"));
        columnConfigs.add(ColumnConfig.of("父级分类名称", "categoryParentName"));
        columnConfigs.add(ColumnConfig.of("品牌ID", "brandId"));
        columnConfigs.add(ColumnConfig.of("品牌名称", "brandName"));
        columnConfigs.add(ColumnConfig.of("供应商ID", "supplierId"));
        columnConfigs.add(ColumnConfig.of("供应商名称", "supplierName"));
        columnConfigs.add(ColumnConfig.of("计量单位ID", "unitId"));
        columnConfigs.add(ColumnConfig.of("计量单位名称", "unitName"));
        columnConfigs.add(ColumnConfig.of("产地ID", "originId"));
        columnConfigs.add(ColumnConfig.of("产地名称", "originName"));
        columnConfigs.add(ColumnConfig.of("仓库ID集合", "warehouseId"));
        columnConfigs.add(ColumnConfig.of("颜色", "color"));
        columnConfigs.add(ColumnConfig.of("进价", "purchasePrice"));
        columnConfigs.add(ColumnConfig.of("售价", "sellingPrice"));
        columnConfigs.add(ColumnConfig.of("会员价", "memberPrice"));
        columnConfigs.add(ColumnConfig.of("库存数量", "stock"));
        columnConfigs.add(ColumnConfig.of("商品描述", "description"));
        columnConfigs.add(ColumnConfig.of("生产日期", "productionDate"));
        columnConfigs.add(ColumnConfig.of("保质期", "shelfLife"));
        columnConfigs.add(
                ColumnConfig.of("状态", "status")
                        .withFormatter(value -> {
                            try {
                                if(value instanceof Boolean){
                                    return Boolean.TRUE.equals(value) ? "上架" : "下架";
                                }
                                else{
                                    return "未知";
                                }
                            }
                            catch (Exception e) {
                                return "未知";
                            }
                        })
        );
        columnConfigs.add(ColumnConfig.of("创建时间", "createTime"));
        // 3. 设置响应头
        ExcelUtils.setExcelResponseHeader(response, "商品列表");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(products, columnConfigs, response.getOutputStream());
    }

    /**
     * 导出采购清单
     */
    @GetMapping("/purchase-lists/export")
    @Operation(summary = "导出采购清单")
    @ApiOperationLog(description = "导出采购清单")
    public void exportPurchaseLists(HttpServletResponse response) throws IOException {
        // 1. 获取数据
        List<ProductStockListVO> purchaseLists = productStockService.getAllPurchaseLists();
        // 2. 配置Excel列
        List<ColumnConfig> columnConfigs = new ArrayList<>();
        columnConfigs.add(ColumnConfig.of("ID", "id"));
        columnConfigs.add(ColumnConfig.of("商品名称", "productName"));
        columnConfigs.add(ColumnConfig.of("仓库名称", "warehouseName"));
        columnConfigs.add(ColumnConfig.of("计划数量", "planCount"));
        columnConfigs.add(ColumnConfig.of("实际数量", "actualCount"));
        columnConfigs.add(ColumnConfig.of("采购人", "buyer"));
        columnConfigs.add(ColumnConfig.of("采购日期", "buyDate").withDateFormat("yyyy-MM-dd"));
        columnConfigs.add(ColumnConfig.of("采购人电话", "buyerPhone"));
        columnConfigs.add(
                ColumnConfig.of("入库状态", "status")
                .withFormatter(value -> {
                    try{
                        switch ((Integer)value) {
                            case 0:
                                return "未入库";
                            case 1:
                                return "已入库";
                            default:
                                return "未知";
                        }
                    }
                    catch (Exception e) {
                        return "未知";
                    }
                })
        );
        // 3. 设置响应头
        ExcelUtils.setExcelResponseHeader(response, "采购清单");
        // 4. 导出Excel
        ExcelUtils.exportToOutputStream(purchaseLists, columnConfigs, response.getOutputStream());
    }
} 